PostAgent can (somewhat incongruently) make GET requests now.

Andrew Cantino 11 years ago
parent
commit
19bbbe4bfe
2 changed files with 111 additions and 19 deletions
  1. 37 4
      app/models/agents/post_agent.rb
  2. 74 15
      spec/models/agents/post_agent_spec.rb

+ 37 - 4
app/models/agents/post_agent.rb

@@ -5,7 +5,9 @@ module Agents
5 5
     default_schedule "never"
6 6
 
7 7
     description <<-MD
8
-      A PostAgent receives events from other agents (or runs periodically), merges those events with the contents of `payload`, and sends the results as POST requests to a specified url. The `post_url` field must specify where you would like to send requests.  Please include the URI scheme (`http` or `https`).
8
+      A PostAgent receives events from other agents (or runs periodically), merges those events with the contents of `payload`, and sends the results as POST (or GET) requests to a specified url.
9
+
10
+      The `post_url` field must specify where you would like to send requests. Please include the URI scheme (`http` or `https`).
9 11
     MD
10 12
 
11 13
     event_description "Does not produce events."
@@ -14,6 +16,7 @@ module Agents
14 16
       {
15 17
         'post_url' => "http://www.example.com",
16 18
         'expected_receive_period_in_days' => 1,
19
+        'method' => 'post',
17 20
         'payload' => {
18 21
           'key' => 'value'
19 22
         }
@@ -24,6 +27,10 @@ module Agents
24 27
       last_receive_at && last_receive_at > options['expected_receive_period_in_days'].to_i.days.ago && !recent_error_logs?
25 28
     end
26 29
 
30
+    def method
31
+      (options['method'].presence || 'post').to_s.downcase
32
+    end
33
+
27 34
     def validate_options
28 35
       unless options['post_url'].present? && options['expected_receive_period_in_days'].present?
29 36
         errors.add(:base, "post_url and expected_receive_period_in_days are required fields")
@@ -32,25 +39,51 @@ module Agents
32 39
       if options['payload'].present? && !options['payload'].is_a?(Hash)
33 40
         errors.add(:base, "if provided, payload must be a hash")
34 41
       end
42
+
43
+      unless %w[post get].include?(method)
44
+        errors.add(:base, "method must be 'post' or 'get'")
45
+      end
35 46
     end
36 47
 
37 48
     def receive(incoming_events)
38 49
       incoming_events.each do |event|
39
-        post_data (options['payload'].presence || {}).merge(event.payload)
50
+        handle (options['payload'].presence || {}).merge(event.payload)
40 51
       end
41 52
     end
42 53
 
43 54
     def check
44
-      post_data options['payload'].presence || {}
55
+      handle options['payload'].presence || {}
56
+    end
57
+
58
+    def generate_uri(params = nil)
59
+      uri = URI options[:post_url]
60
+      uri.query = URI.encode_www_form(Hash[URI.decode_www_form(uri.query)].merge(params)) if params
61
+      uri
45 62
     end
46 63
 
47 64
     private
48 65
 
66
+    def handle(data)
67
+      if method == 'post'
68
+        post_data(data)
69
+      elsif method == 'get'
70
+        get_data(data)
71
+      else
72
+        error "Invalid method '#{method}'"
73
+      end
74
+    end
75
+
49 76
     def post_data(data)
50
-      uri = URI options[:post_url]
77
+      uri = generate_uri
51 78
       req = Net::HTTP::Post.new(uri.request_uri)
52 79
       req.form_data = data
53 80
       Net::HTTP.start(uri.hostname, uri.port, :use_ssl => uri.scheme == "https") { |http| http.request(req) }
54 81
     end
82
+
83
+    def get_data(data)
84
+      uri = generate_uri(data)
85
+      req = Net::HTTP::Get.new(uri.request_uri)
86
+      Net::HTTP.start(uri.hostname, uri.port, :use_ssl => uri.scheme == "https") { |http| http.request(req) }
87
+    end
55 88
   end
56 89
 end

+ 74 - 15
spec/models/agents/post_agent_spec.rb

@@ -26,8 +26,10 @@ describe Agents::PostAgent do
26 26
       }
27 27
     }
28 28
 
29
-    @sent_messages = []
30
-    stub.any_instance_of(Agents::PostAgent).post_data { |event| @sent_messages << event }
29
+    @sent_posts = []
30
+    @sent_gets = []
31
+    stub.any_instance_of(Agents::PostAgent).post_data { |data| @sent_posts << data }
32
+    stub.any_instance_of(Agents::PostAgent).get_data { |data| @sent_gets << data }
31 33
   end
32 34
 
33 35
   describe "#receive" do
@@ -41,21 +43,46 @@ describe Agents::PostAgent do
41 43
       }
42 44
 
43 45
       lambda {
44
-        @checker.receive([@event, event1])
45
-      }.should change { @sent_messages.length }.by(2)
46
+        lambda {
47
+          @checker.receive([@event, event1])
48
+        }.should change { @sent_posts.length }.by(2)
49
+      }.should_not change { @sent_gets.length }
46 50
 
47
-      @sent_messages[0].should == @event.payload.merge('default' => 'value')
48
-      @sent_messages[1].should == event1.payload
51
+      @sent_posts[0].should == @event.payload.merge('default' => 'value')
52
+      @sent_posts[1].should == event1.payload
53
+    end
54
+
55
+    it "can make GET requests" do
56
+      @checker.options['method'] = 'get'
57
+
58
+      lambda {
59
+        lambda {
60
+          @checker.receive([@event])
61
+        }.should change { @sent_gets.length }.by(1)
62
+      }.should_not change { @sent_posts.length }
63
+
64
+      @sent_gets[0].should == @event.payload.merge('default' => 'value')
49 65
     end
50 66
   end
51 67
 
52 68
   describe "#check" do
53
-    it "sends options['payload']" do
69
+    it "sends options['payload'] as a POST request" do
54 70
       lambda {
55 71
         @checker.check
56
-      }.should change { @sent_messages.length }.by(1)
72
+      }.should change { @sent_posts.length }.by(1)
73
+
74
+      @sent_posts[0].should == @checker.options['payload']
75
+    end
76
+
77
+    it "sends options['payload'] as a GET request" do
78
+      @checker.options['method'] = 'get'
79
+      lambda {
80
+        lambda {
81
+          @checker.check
82
+        }.should change { @sent_gets.length }.by(1)
83
+      }.should_not change { @sent_posts.length }
57 84
 
58
-      @sent_messages[0].should == @checker.options['payload']
85
+      @sent_gets[0].should == @checker.options['payload']
59 86
     end
60 87
   end
61 88
 
@@ -76,27 +103,59 @@ describe Agents::PostAgent do
76 103
     end
77 104
 
78 105
     it "should validate presence of post_url" do
79
-      @checker.options[:post_url] = ""
106
+      @checker.options['post_url'] = ""
80 107
       @checker.should_not be_valid
81 108
     end
82 109
 
83 110
     it "should validate presence of expected_receive_period_in_days" do
84
-      @checker.options[:expected_receive_period_in_days] = ""
111
+      @checker.options['expected_receive_period_in_days'] = ""
112
+      @checker.should_not be_valid
113
+    end
114
+
115
+    it "should validate method as post or get, defaulting to post" do
116
+      @checker.options['method'] = ""
117
+      @checker.method.should == "post"
118
+      @checker.should be_valid
119
+
120
+      @checker.options['method'] = "POST"
121
+      @checker.method.should == "post"
122
+      @checker.should be_valid
123
+
124
+      @checker.options['method'] = "get"
125
+      @checker.method.should == "get"
126
+      @checker.should be_valid
127
+
128
+      @checker.options['method'] = "wut"
129
+      @checker.method.should == "wut"
85 130
       @checker.should_not be_valid
86 131
     end
87 132
 
88 133
     it "should validate payload as a hash, if present" do
89
-      @checker.options[:payload] = ""
134
+      @checker.options['payload'] = ""
90 135
       @checker.should be_valid
91 136
 
92
-      @checker.options[:payload] = "hello"
137
+      @checker.options['payload'] = "hello"
93 138
       @checker.should_not be_valid
94 139
 
95
-      @checker.options[:payload] = ["foo", "bar"]
140
+      @checker.options['payload'] = ["foo", "bar"]
96 141
       @checker.should_not be_valid
97 142
 
98
-      @checker.options[:payload] = { 'this' => 'that' }
143
+      @checker.options['payload'] = { 'this' => 'that' }
99 144
       @checker.should be_valid
100 145
     end
101 146
   end
147
+
148
+  describe "#generate_uri" do
149
+    it "merges params with any in the post_url" do
150
+      @checker.options['post_url'] = "http://example.com/a/path?existing_param=existing_value"
151
+      uri = @checker.generate_uri("some_param" => "some_value", "another_param" => "another_value")
152
+      uri.request_uri.should == "/a/path?existing_param=existing_value&some_param=some_value&another_param=another_value"
153
+    end
154
+
155
+    it "just returns the post_uri when no params are given" do
156
+      @checker.options['post_url'] = "http://example.com/a/path?existing_param=existing_value"
157
+      uri = @checker.generate_uri
158
+      uri.request_uri.should == "/a/path?existing_param=existing_value"
159
+    end
160
+  end
102 161
 end